//++++++++++++++++++++++++++++++++++++
// Z Graphics 2.5 Post-Effects
// COPYRIGHT - ZIMMER, ICELAGLACE, BORIS VORONTSOV
// DO NOT COPY, DISTRIBUTE OR MODIFY THIS CODE WITHOUT PERMISSION
//++++++++++++++++++++++++++++++++++++

#include "enbshaders.txt"

// enb values
float4 Timer;
float4 ScreenSize;

// textures
texture2D texColor;
texture2D texNoise;

// samplers
sampler2D SamplerColor = sampler_state
{
Texture   = <texColor>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = NONE;
AddressU  = Clamp;
AddressV  = Clamp;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};

sampler2D SamplerNoise = sampler_state
{
Texture   = <texNoise>;
MinFilter = POINT;
MagFilter = POINT;
MipFilter = NONE;
AddressU  = Wrap;
AddressV  = Wrap;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};

// vs
struct VS_OUTPUT_POST {
float4 vpos  : POSITION;
float2 txcoord : TEXCOORD0;
};
struct VS_OUTPUT_DOF {
float4 vpos  : POSITION;
float2 txcoord : TEXCOORD0;
float focaldepth: TEXCOORD1;
};

struct VS_INPUT_POST {
float3 pos  : POSITION;
float2 txcoord : TEXCOORD0;
};

// custom code begin here...
float zw(float f){return 1.f-1.f/f;}
float pp(){float f=0,S=.05;for(int r=0;r<6;r++){float t=(float)r;t*=3.1415*2/6;float2 e=float2(cos(t),sin(t));e.y*=ScreenSize.z;e*=S;float z=zw(tex2Dlod(SamplerColor,float4(e+float2(.5,.4),0,0)).w);f+=z;}return f/6;}
VS_OUTPUT_DOF VS_DOF(VS_INPUT_POST s){VS_OUTPUT_DOF d;float4 y=float4(s.pos.x,s.pos.y,s.pos.z,1.);d.vpos=y;d.txcoord.xy=s.txcoord.xy;d.focaldepth=pp();return d;}
float3 v(float3 clr,float2 coord){float M=0.01;float t=pow(distance(coord.xy,float2(.5,.5)),3.);

float rC=tex2D(SamplerColor,coord.xy+float2(M*t,.0)).r;float gC=tex2D(SamplerColor,coord.xy).g;
float bC=tex2D(SamplerColor,coord.xy-float2(M*t,.0)).b;

clr=float3(rC,gC,bC);



return clr;

}

static const float cf=Timer.x*15000.;static const float2 sh=float2(ScreenSize.x,ScreenSize.x*ScreenSize.w);float4 pa(float2 p){float4 p4=frac(p.xyxy*float4(443.8975,397.2973,491.1871,470.7827));p4+=dot(p4.wzxy,p4+19.19);return frac(p4.xxyx*p4.yzww);}float pb(float n){return frac(sin(n)*43758.5453123);}float rand(in float2 u){float2 y=(frac(sin(dot(u,float2(12.9898,78.233)*2.))*43758.5453));return abs(y.x+y.y)*.5;}
VS_OUTPUT_POST VS_PostProcess(VS_INPUT_POST s){VS_OUTPUT_POST d;float4 y=float4(s.pos.x,s.pos.y,s.pos.z,1.);d.vpos=y;d.txcoord.xy=s.txcoord.xy;return d;}
float n(float3 x){float3 p=floor(x);float3 f=frac(x);f*=f*(3.-2.*f);float n=dot(p,float3(1.,57.,113.));return lerp(lerp(lerp(pb(n+0.),pb(n+1.),f.x),lerp(pb(n+57.),pb(n+58.),f.x),f.y),lerp(lerp(pb(n+113.),pb(n+114.),f.x),lerp(pb(n+170.),pb(n+171.),f.x),f.y),f.z);}
float nn(float2 uv){float v=-cf*2.;v=(n(float3(uv.y*.01+v,1.,1.))+.0)*(n(float3(uv.y*.011+1000.+v,1.,1.))+.0)*(n(float3(uv.y*.51+421.+v,1.,1.))+.0);v*=pa(float2(uv.x+v*.01,uv.y)).x+.3;return min(pow(v,10.)*15.,1.);}
float4 tvn(float4 color,float2 coord){const float T=sh.y/740.;float2 pos=coord*sh;float4 uv;uv.xy=floor(pos/T)*T;uv.zw=ceil(pos/T)*T;float2 w=(pos-uv.xy)/T;return float4(lerp(color.rgb,58.0*.01,lerp(lerp(nn(uv.xy),nn(uv.xw),w.y),lerp(nn(uv.zy),nn(uv.zw),w.y),w.x)),color.a);}
float4 DOF_Pass(VS_OUTPUT_DOF p,float2 w:VPOS):COLOR{float2 t=p.txcoord.xy;
#if (DEPTHOFFIELD==1)
int f=6;float l=.5;int z=3;float S=.7,r=2,s=0,D=1.,y=4;float4 i=tex2D(SamplerColor,t);i.xyz*=lerp(S,r,pow(0,s));float3 I=v(I,t);I=pow(i.xyz,y);float m=1,c=1,x=zw(i.w),o=pp();float h=abs(x-o);h=sqrt(h/2.);if(x<o)h/=4;h=min(h,1.);float a=1.f/ScreenSize.x*(3*z*2)*h;int M=max(1,ceil((float)z*h));a*=(float)z/(float)(M+1);for(int e=0;e<M;e++){for(int n=0;n<f;n++){float O=(float)n;O*=3.1415*2/(float)f;O+=.37;float2 F=float2(cos(O),sin(O)),C=float2(cos(O+3.1415*2/(float)f),sin(O+3.1415*2/(float)f));for(float d=0;d<1.f;d+=1.f/((float)e+1)){float U=(float)e/(float)z;float2 T=lerp(F,C,d);T.y*=ScreenSize.z;float G=1;float4 L=tex2D(SamplerColor,t+T*a*(e+1)/z);L.xyz*=lerp(S,r,pow(U,s));L.xyz=pow(L.xyz,y);float E=zw(L.w);if(E<x*1.3&&E<o*.5)G=0;I+=L.xyz*G;m+=G;c+=1;}}}I/=m;I=pow(I,1.f/y);I*=l;return float4(I,h*(m/c));
#else
float4 G=tex2D(SamplerColor,p.txcoord.xy);return G;
#endif
}
float4 Cinema(VS_OUTPUT_POST x):COLOR{float4 r=tex2D(SamplerColor,x.txcoord.xy);
#if (CINEMA==1)
r.xyz=x.txcoord.y>.1&&x.txcoord.y<.9?r.xyz:0;
#endif
return r;
}
float4 Noise(VS_OUTPUT_POST f):COLOR{float4 q=tex2D(SamplerColor,f.txcoord);  
#if (NOISE==1)
float an=Timer.x*1.6784738;float2 t=f.txcoord.xy*1.,ac=t+float2(0.,an),k=t+float2(an,0.),d=t+float2(an,an);float l=(rand(ac)+rand(k)+rand(d))*.333;float3 G=l,e=float3(rand(ac),rand(k),rand(d));q.rgb+=(lerp(G,e,1.)*.033)-(.033*.5);
#endif
return q;
}
float4 FishEye(VS_OUTPUT_POST t):COLOR{
#if (LENS_DISTORTION==1) 
float4 s;float4 J=0.;J.xy=t.txcoord.xy;float4 o;J.w=0.;o=tex2D(SamplerColor,J);
float4 I=o;float2 invscreensize=1./ScreenSize;invscreensize.y=invscreensize.y/ScreenSize.z;float2 e;e.x=J.x-.5;e.y=J.y-.5;float m=1./.6,r2=(t.txcoord.x-.5)*(t.txcoord.x-.5)+(t.txcoord.y-.5)*(t.txcoord.y-.5);float f=0;{f=1+r2*.3;};float x=f*m*(J.x-.5)+.5,y=f*m*(J.y-.5)+.5;float2 xC=f*m*(e.xy*.5)+.5,yC=f*m*(e.xy*.5)+.5,zC=f*m*(e.xy*.5)+.5;float4 u=float4(tex2D(SamplerColor,xC).x,tex2D(SamplerColor,yC).y,tex2D(SamplerColor,zC).z,tex2D(SamplerColor,float2(x,y)).a);return float4(u.x,u.y,u.z,1);s.w=1;
#else
float4 s=tex2D(SamplerColor, t.txcoord.xy);
#endif
return s;
}
float4 ChromaticAbberation(VS_OUTPUT_POST x):COLOR{
#if (CHROMATIC_ABERRATION==1)
float4 c=tex2D(SamplerColor,x.txcoord.xy);float2 coord=x.txcoord.xy;
c.rgb=v(c.rgb,coord);
#else
float4 c=tex2D(SamplerColor,x.txcoord.xy);
#endif
return c;
}
float4 AA(VS_OUTPUT_POST i):COLOR{float4 noaa=tex2D(SamplerColor,i.txcoord.xy);
#if (FXAA==1)
float xy=3,ZIMMER=1,r=.5,fss=1./16,fma=1./32,fnm=1./128,faa=4;float2 fr=float2(1/ScreenSize.x, 1/(ScreenSize.x/ScreenSize.z));float4 P;P.xy=i.txcoord.xy;P.zw=P.xy-(fr.xy*(.5+fss));float3 NW=tex2D(SamplerColor,P.zw).xyz,NE=tex2D(SamplerColor,P.zw+float2(fr.x,.0)).xyz,SW=tex2D(SamplerColor,P.zw+float2(.0,fr.y)).xyz,SE=tex2D(SamplerColor,P.zw+fr.xy).xyz,M=tex2D(SamplerColor,P.xy).xyz;float3 luma=float3(.299,.587,.114);float lNW=dot(NW, luma),lNE=dot(NE,luma),lSW=dot(SW,luma),lSE=dot(SE,luma),lM=dot(M,luma);float lmin=min(lM,min(min(lNW,lNE),min(lSW, lSE))),lmax=max(lM,max(max(lNW,lNE),max(lSW,lSE)));
float2 dir; float NWNE=lNW+lNE,SWSE=lSW+lSE;dir.x=-((NWNE)-(SWSE));dir.y=((lNW+lSW)-(lNE+lSE));float dirReduce=max((SWSE+NWNE)*(.25*fnm),fma);float rcpDirMin=ZIMMER/(min(abs(dir.x),abs(dir.y))+dirReduce);dir=min(float2(faa,faa),max(float2(-faa,-faa),dir*rcpDirMin))*fr.xy;float3 rgbA=(ZIMMER/2.)*(tex2D(SamplerColor,P.xy+dir*(ZIMMER/3.-.5)).xyz+tex2D(SamplerColor,P.xy+dir*(2./3.-.5) ).xyz);float3 rgbB=rgbA*(ZIMMER/2.)+(ZIMMER/4.)*(tex2D(SamplerColor,P.xy+dir*(.0/3.-.5)).xyz+tex2D(SamplerColor,P.xy+dir*(3./3.-.5)).xyz);float lumaB=dot(rgbB,luma);if((lumaB<lmin)||(lumaB>lmax))return float4(rgbA,1);return float4(rgbB,1);
#else
return noaa;
#endif
}
float4 VHS(VS_OUTPUT_POST f):COLOR{float4 S=tex2D(SamplerColor,f.txcoord);
#if (VHS_NOISE==1)  
S=lerp(S,tvn(S,f.txcoord),2.);
#endif
return S;}

technique PostProcess
{
   pass P0
   {
VertexShader = compile vs_3_0 VS_DOF();
PixelShader  = compile ps_3_0 DOF_Pass();

FogEnable=FALSE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}

technique PostProcess2
{
   pass P0
   {
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader  = compile ps_3_0 Cinema();

FogEnable=FALSE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}

technique PostProcess3
{
   pass P0
   {
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader  = compile ps_3_0 Noise();

FogEnable=FALSE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}

technique PostProcess4
{
   pass P0
   {
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader  = compile ps_3_0 FishEye();

FogEnable=FALSE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}

technique PostProcess5
{
   pass P0
   {
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader  = compile ps_3_0 ChromaticAbberation();

FogEnable=FALSE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}

technique PostProcess6
{
   pass P0
   {
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader  = compile ps_3_0 AA();

FogEnable=FALSE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}

technique PostProcess7
{
   pass P0
   {
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader  = compile ps_3_0 VHS();

FogEnable=FALSE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
